#!/usr/bin/env python3
# Copyright (c) 2021 maminjie <canpool@163.com>
# SPDX-License-Identifier: MulanPSL-2.0

"""
This script is based on github REST API, to manage repositories on the github.com

Reference https://docs.github.com/en/rest/reference
"""

import sys
import os
import json
import urllib
import urllib.request
import urllib.parse
import urllib.error


class Github(object):
    """
    Github is a helper class to abstract github.com api
    """
    def __init__(self):
        self.headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW 64; rv:50.0) Gecko/20100101 Firefox/50.0'
            }

    def http_request(self, url, data=None, headers={}, method=None):
        url = "https://api.github.com" + url
        req = urllib.request.Request(url=url, data=data, headers=headers, method=method)
        try:
            result = urllib.request.urlopen(req)
            return result.read().decode("utf-8")
        except urllib.error.HTTPError as e:
            print("{} ERROR: ".format(method) + str(url).split("?")[0])
            print("{} ERROR: ".format(method) + str(e.code) + " " + e.reason)
            return None
        except urllib.error.URLError as e:
            print("{} ERROR: ".format(method) + str(url).split("?")[0])
            print("{} ERROR: ".format(method) + e.reason)
            return None

    def get_request(self, url, headers=None):
        if headers is None:
            headers = self.headers.copy()
        return self.http_request(url=url, headers=headers, method="GET")

    def get_json(self, url):
        headers = self.headers.copy()
        headers["Content-Type"] = "application/json;charset=UTF-8"
        resp = self.get_request(url, headers)
        if resp is None:
            return None
        if resp:
            return json.loads(resp)
        return resp

    def get(self, url, param=""):
        return self.get_json(url + param)

    def get_org_repos(self, org, repo_type, page=1, per_page=100):
        """
        repo_type - all, public, private
        """
        url_template = "/orgs/{ORG}/repos"
        url = url_template.format(ORG=org)
        param = "?type={}&page={}&per_page={}".format(repo_type, page, per_page)
        return self.get(url, param)

    def get_user_repos(self, username, repo_type, page=1, per_page=100):
        """
        repo_type - all, owner, member
        """
        url_template = "/users/{username}/repos"
        url = url_template.format(username=username)
        param = "?type={}&sort=full_name&page={}&per_page={}".format(repo_type, page, per_page)
        return self.get(url, param)

    def get_one_repo(self, owner, repo):
        url_template = "/repos/{owner}/{repo}"
        url = url_template.format(owner=owner, repo=repo)
        return self.get(url)

    def get_tags(self, owner, repo, page=1, per_page=100):
        url_template = "/repos/{owner}/{repo}/tags"
        url = url_template.format(owner=owner, repo=repo)
        param = "?page={}&per_page={}".format(page, per_page)
        return self.get(url, param)

    def get_commits(self, owner, repo, sha="", author="", since="", until="", page=1, per_page=100):
        url_template = "/repos/{owner}/{repo}/commits"
        url = url_template.format(owner=owner, repo=repo)
        param = "?page={}&per_page={}".format(page, per_page)
        if sha:
            param += "&sha={}".format(sha)
        if author:
            param += "&author={}".format(author)
        if since:
            param += "&since={}".format(since)
        if until:
            param += "&until={}".format(until)
        return self.get(url, param)

    def get_one_commit(self, owner, repo, ref):
        url_template = "/repos/{owner}/{repo}/commits/{ref}"
        url = url_template.format(owner=owner, repo=repo, ref=ref)
        return self.get(url)

    def get_releases(self, owner, repo, page=1, per_page=100):
        url_template = "/repos/{owner}/{repo}/releases"
        url = url_template.format(owner=owner, repo=repo)
        param = "?page={}&per_page={}".format(page, per_page)
        return self.get(url, param)


if __name__ == "__main__":
    pass
